package cn.cdu.doctor.task;

import cn.cdu.doctor.entity.AutoSchedulingConfig;
import cn.cdu.doctor.entity.DoctorScheduling;
import cn.cdu.doctor.service.IAutoSchedulingConfigService;
import cn.cdu.doctor.service.IDoctorSchedulingService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Component
public class AutoSchedulingTask {

    @Autowired
    private IAutoSchedulingConfigService autoSchedulingConfigService;

    @Autowired
    private IDoctorSchedulingService doctorSchedulingService;

    @Scheduled(cron = "0 0 * * * ?") // 每小时执行一次，在每小时的0分0秒执行
    public void autoScheduling() {
        log.info("开始执行自动放号任务");
        LocalDateTime now = LocalDateTime.now();
        String currentTime = now.format(DateTimeFormatter.ofPattern("HH:mm"));

        // 查询所有启用的配置
        QueryWrapper<AutoSchedulingConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enabled", 1);
        List<AutoSchedulingConfig> configs = autoSchedulingConfigService.list(queryWrapper);

        for (AutoSchedulingConfig config : configs) {
            // 检查是否到达放号时间
            if (!currentTime.equals(config.getScheduleTime())) {
                continue;
            }

            // 获取当前是周几
            DayOfWeek currentDayOfWeek = now.getDayOfWeek();
            int currentWeekDay = currentDayOfWeek.getValue();
            
            // 检查是否在配置的放号日期中
            List<String> weekDays = Arrays.asList(config.getWeekDays().split(","));
            if (!weekDays.contains(String.valueOf(currentWeekDay))) {
                continue;
            }

            // 计算放号日期
            LocalDate scheduleDate = now.toLocalDate().plusDays(config.getAdvanceDays());
            
            // 检查是否已经存在该日期的排班
            QueryWrapper<DoctorScheduling> schedulingQuery = new QueryWrapper<>();
            schedulingQuery.eq("doctor_id", config.getDoctorId())
                          .eq("date", scheduleDate.format(DateTimeFormatter.ISO_LOCAL_DATE))
                          .eq("step", config.getStep());
            
            if (doctorSchedulingService.count(schedulingQuery) > 0) {
                log.info("医生{}在{}的{}时段已有排班，跳过自动放号", 
                    config.getDoctorName(), 
                    scheduleDate, 
                    "0".equals(config.getStep()) ? "上午" : "下午");
                continue;
            }

            // 执行放号
            try {
                List<DoctorScheduling> schedulingList = new java.util.ArrayList<>();
                for (int i = 1; i <= config.getNumber(); i++) {
                    DoctorScheduling ds = new DoctorScheduling();
                    ds.setDoctorId(config.getDoctorId());
                    ds.setDoctorName(config.getDoctorName());
                    ds.setNumber(i + "");
                    ds.setStep(config.getStep());
                    ds.setDate(scheduleDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
                    ds.setOrderFlag(0);
                    schedulingList.add(ds);
                }
                doctorSchedulingService.saveBatch(schedulingList);
                log.info("自动放号成功：医生{}在{}的{}时段放号{}个", 
                    config.getDoctorName(), 
                    scheduleDate, 
                    "0".equals(config.getStep()) ? "上午" : "下午",
                    config.getNumber());
            } catch (Exception e) {
                log.error("自动放号失败：", e);
            }
        }
    }
} 